using System;

namespace SeaVM.Instructions
{
    public class Le
    {
        public static Instruction Create()
        {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.Le;
            return inst;
        }

        public static Instruction Create(int address)
        {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.Le;
            InstructionArg arg1 = new InstructionArg();
            arg1.type = InstructionArgType.Address;
            arg1.address = address;
            inst.args.Add(arg1);
            return inst;
        }

        public static Instruction Create(string define)
        {
            Instruction inst = new Instruction();
            inst.opcode = Opcode.Le;
            InstructionArg arg1 = new InstructionArg();
            arg1.type = InstructionArgType.Define;
            arg1.define = define;
            inst.args.Add(arg1);
            return inst;
        }

        public static Data Calc(VM vm)
        {
            if(vm.stack.Count < 2)
                throw new VmRunError("栈中的数据小于两个，无法进行计算");
            Data a = vm.stack.Pop();
            Data b = vm.stack.Pop();
            return a < b;
        }
        public static void Run(VM vm,Instruction inst)
        {
            if(inst.args.Count == 0)
            {
                vm.stack.Push(Calc(vm));
                vm.line++;
                return;
            }
            InstructionArg arg1 = inst.args[0];
            switch(arg1.type)
            {
                case InstructionArgType.Address:
                {
                    if(arg1.address < 0 || arg1.address >= vm.memory.size)
                    {
                        throw new VmRunError("地址越界");
                    }
                    Data data = Calc(vm);
                    vm.memory.Write(data,arg1.address);
                    break;
                }
                case InstructionArgType.Define:
                {
                    if(!vm.defines.ContainsKey(arg1.define))
                    {
                        throw new VmRunError("没有这个定义");
                    }
                    int address = vm.defines[arg1.define];
                    if(address < 0 || address >= vm.memory.size)
                    {
                        throw new VmRunError("地址越界");
                    }
                    Data data = Calc(vm);
                    vm.memory.Write(data,address);
                    break;
                }
                default:throw new VmRunError("指令没有这种形式");
            }
            vm.line++;
        }
    }
}